﻿using Microsoft.Extensions.Logging;
using ST.Common.Util;
using ST.Common.Util.Text;
using ST.Common.Util.Xml;
using ST.WX.Common.Exceptions;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Web;
using System.Xml;

namespace ST.WX.Common.Pay
{
	public class WXPayUnifiedOrderData : WXPayData
	{
		/// <summary>
		/// 子商户公众账号ID
		/// </summary>
		[Display(Name = "子商户公众账号ID")]
		[StringLength(32)]
		public string sub_appid { get; set; }

		/// <summary>
		/// 子商户号
		/// </summary>
		[Display(Name = "子商户号")]
		[StringLength(32)]
		public string sub_mch_id { get; set; }

		/// <summary>
		/// 设备号
		/// </summary>
		[Display(Name = "设备号")]
		[StringLength(32)]
		public string device_info { get; set; }

		/// <summary>
		/// 商品描述
		/// </summary>
		[Required]
		[Display(Name = "商品描述")]
		[StringLength(128)]
		public string body { get; set; }

		/// <summary>
		/// 商品详情
		/// </summary>
		[Display(Name = "商品详情")]
		[StringLength(6000)]
		public string detail { get; set; }

		/// <summary>
		/// 附加数据
		/// </summary>
		[Display(Name = "附加数据")]
		[StringLength(127)]
		public string attach { get; set; }

		/// <summary>
		/// 商户订单号
		/// </summary>
		[Required]
		[Display(Name = "商户订单号")]
		[StringLength(32)]
		public string out_trade_no { get; set; }

		/// <summary>
		/// 标价币种（符合ISO 4217标准的三位字母代码，默认人民币：CNY）
		/// </summary>
		[Display(Name = "标价币种")]
		[StringLength(16)]
		public string fee_type { get; set; }

		/// <summary>
		/// 标价金额（订单总金额，单位为分）
		/// </summary>
		[Display(Name = "标价金额")]
		public int total_fee { get; set; }

		/// <summary>
		/// 终端IP（支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP）
		/// </summary>
		[Display(Name = "终端IP")]
		[StringLength(64)]
		public string spbill_create_ip { get; set; }

		/// <summary>
		/// 交易起始时间（订单生成时间，格式为yyyyMMddHHmmss）
		/// </summary>
		[Display(Name = "交易起始时间")]
		[StringLength(14)]
		public string time_start { get; set; }

		/// <summary>
		/// 交易结束时间（订单失效时间，格式为yyyyMMddHHmmss，建议：最短失效时间间隔大于1分钟）
		/// </summary>
		[Display(Name = "交易结束时间")]
		[StringLength(14)]
		public string time_expire { get; set; }

		/// <summary>
		/// 订单优惠标记（订单优惠标记，使用代金券或立减优惠功能时需要的参数）
		/// </summary>
		[Display(Name = "订单优惠标记")]
		[StringLength(32)]
		public string goods_tag { get; set; }

		/// <summary>
		/// 通知地址（异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数）
		/// </summary>
		[Required]
		[Display(Name = "通知地址")]
		[StringLength(256)]
		public string notify_url { get; set; }

		/// <summary>
		/// 交易类型（JSAPI--JSAPI支付（或小程序支付）、NATIVE--Native支付、APP--app支付，MWEB--H5支付，不同trade_type决定了调起支付的方式，请根据支付产品正确上传）
		/// </summary>
		[Required]
		[Display(Name = "交易类型")]
		[StringLength(16)]
		public string trade_type { get; set; }

		/// <summary>
		/// 商品ID（trade_type=NATIVE时，此参数必传。此参数为二维码中包含的商品ID，商户自行定义。）
		/// </summary>
		[Display(Name = "商品ID")]
		[StringLength(32)]
		public string product_id { get; set; }

		/// <summary>
		/// 指定支付方式（上传此参数no_credit--可限制用户不能使用信用卡支付）
		/// </summary>
		[Display(Name = "指定支付方式")]
		[StringLength(32)]
		public string limit_pay { get; set; }

		/// <summary>
		/// 用户子标识（trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识）
		/// </summary>
		[Display(Name = "用户标识")]
		[StringLength(128)]
		public string openid { get; set; }

		/// <summary>
		/// 用户子标识（trade_type=JSAPI，此参数必传，用户在子商户appid下的唯一标识。openid和sub_openid可以选传其中之一，如果选择传sub_openid,则必须传sub_appid。）
		/// </summary>
		[Display(Name = "用户子标识")]
		[StringLength(128)]
		public string sub_openid { get; set; }

		/// <summary>
		/// 电子发票入口开放标识
		/// </summary>
		[Display(Name = "电子发票入口开放标识")]
		[StringLength(8)]
		public string receipt { get; set; }

		/// <summary>
		/// 场景信息（该字段常用于线下活动时的场景信息上报，支持上报实际门店信息，商户也可以按需求自己上报相关信息。该字段为JSON对象数据，对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }} ）
		/// </summary>
		[Display(Name = "场景信息")]
		[StringLength(256)]
		public string scene_info { get; set; }

		public WXPayUnifiedOrderData() : base()
		{
		}

		public WXPayUnifiedOrderData(string appID, string mchID, string mchKey, WXPaySignType signType, string svrIP, string notifyUrl) : base(appID, mchID, mchKey, signType)
		{
			notify_url = notifyUrl;
			spbill_create_ip = svrIP;
		}

		public override void Validate()
		{
			base.Validate();

			if (total_fee <= 0)
			{
				throw new WXPayException("统一下单接口中缺少必填参数total_fee");
			}
			//关联参数
			if (trade_type == "JSAPI" && string.IsNullOrEmpty(openid))
			{
				throw new WXPayException("统一下单接口中缺少必填参数openid！trade_type为JSAPI时，openid为必填参数！");
			}
			if (trade_type == "NATIVE" && string.IsNullOrEmpty(product_id))
			{
				throw new WXPayException("统一下单接口中缺少必填参数product_id！trade_type为JSAPI时，product_id为必填参数！");
			}
			if (trade_type == "MWEB" && string.IsNullOrEmpty(sub_mch_id))
			{
				throw new WXPayException("统一下单接口中缺少必填参数sub_mch_id！trade_type为MWEB时，sub_mch_id为必填参数！");
			}
		}

		public override SortedDictionary<string, object> ConvertFromObj()
		{
			SortedDictionary<string, object> values = new SortedDictionary<string, object>();
			values["sub_appid"] = sub_appid;
			values["sub_mch_id"] = sub_mch_id;
			values["device_info"] = device_info;
			values["body"] = body;
			values["detail"] = detail;
			values["attach"] = attach;
			values["out_trade_no"] = out_trade_no;
			values["fee_type"] = fee_type;
			values["total_fee"] = total_fee;
			values["spbill_create_ip"] = spbill_create_ip;
			values["time_start"] = time_start;
			values["time_expire"] = time_expire;
			values["goods_tag"] = goods_tag;
			values["notify_url"] = notify_url;
			values["trade_type"] = trade_type;
			values["product_id"] = product_id;
			values["limit_pay"] = limit_pay;
			values["openid"] = openid;
			values["sub_openid"] = sub_openid;
			values["receipt"] = receipt;
			values["scene_info"] = scene_info;
			return values;
		}
	}
}
